package org.example.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.example.Domain.Player;
import org.example.Dto.AgentDTO;
import org.example.Dto.CommunityDTO;
import org.example.Dto.LearnHistoryDTO;
import org.example.Dto.StoryDTO;
import org.example.Dto.WordBookDTO;
import org.example.Entity.Comment;
import org.example.Entity.Community;
import org.example.Entity.Question;
import org.example.Entity.User;
import org.example.Entity.WordBook;
import org.example.Listener.CharacterSimulationListener;
import org.example.Service.*;
import org.example.Utils.OSSUtil;
import org.example.Utils.SendSmsUtil;
import org.example.Vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/word")
public class WordController {

    @Autowired
    private WordService wordService;

    @Autowired
    private WordBookService wordBookService;

    @Autowired
    private LearnHistoryService learnHistoryService;

    @Resource
    private SendSmsUtil sendSmsUtil;

    @Autowired
    private RemindService remindService;

    @Autowired
    private StoryService storyService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private CommunityService communityService;

    @Autowired
    private AiService aiService;

    @Autowired
    private AgentService agentService;

    @Autowired
    private UserService userService;

    @Autowired
    private OSSUtil ossUtil;

    // 用于角色模拟时上一次对话的id
    private String preChatId = "";

    @Autowired
    private CommentService commentService;

    /**
     * 查询单词
     * @param word
     * @return
     * @throws IOException
     */
    @GetMapping("/search")
    public R search(@RequestParam String word) throws IOException {
        return wordService.search(word);
    }

    /**
     * 认识单词
     * @param word
     * @param username
     * @return
     */
    @PostMapping("/know")
    public R know(@RequestBody WordBook word,@RequestParam String username) {
        return wordBookService.know(word,username);
    }

    /**
     * 模糊单词
     * @param word
     * @param username
     * @return
     */
    @PostMapping("/blur")
    public R blur(@RequestBody WordBook word,@RequestParam String username) {
        System.out.println(username);
        return wordBookService.blur(word,username);
    }

    /**
     * 添加一个单词的学习记录
     * @param learnHistoryDTO
     * @return
     */
    @PostMapping("/addLearnHistory")
    public R addLearnHistory(@RequestBody LearnHistoryDTO learnHistoryDTO) {
        return learnHistoryService.addLearnHistory(learnHistoryDTO);
    }

    /**
     * 获取所有知道的单词
     * @param username
     * @return
     */
    @GetMapping("/getAllKnowWord")
    public R getAllKnowWord(String username) {
        return wordBookService.getAllKnowWord(username);
    }

    /**
     * 获取所有模糊的单词
     * @param username
     * @return
     */
    @GetMapping("/getAllBlurWord")
    public R getAllBlurWord(String username) {
        return wordBookService.getAllBlurWord(username);
    }

    /**
     * 根据一个单词本添加单词
     * @param wordBookDTO
     * @param type
     * @return
     */
    @PostMapping("/insertWordByWordBook")
    public R insertWordByWordBook(@RequestBody WordBookDTO wordBookDTO,@RequestParam Integer type) {
        return wordService.insertWordByWordBook(wordBookDTO,type);
    }

    /**
     * 获取最近7天学习记录
     * @param username
     * @return
     */
    @GetMapping("/getRecentSevenDayLearnData")
    public R getRecentSevenDayLearnData(String username) {
        return learnHistoryService.getRecentSevenDayLearnData(username);
    }

    /**
     * 获取当日学习数据
     * @param username
     * @return
     */
    @GetMapping("/getTodayLearnData")
    public R getTodayLearnData(String username) {
        return learnHistoryService.getTodayLearnData(username);
    }

    /**
     * 更新提醒用户的状态
     * @param phone
     * @return
     */
    @PostMapping("/updateRemindUser")
    public R updateRemindUser(@RequestParam String phone) {
        return remindService.updateRemindUser(phone);
    }

    /**
     * 获取提醒用户的状态
      * @param phone
     * @return
     */
    @GetMapping("/getRemindUserStatus")
    public R getRemindUserStatus(@RequestParam String phone) {
        return remindService.getRemindUserStatus(phone);
    }

    /**
     * 语音评测
     * @param file
     * @param text
     * @return
     * @throws Exception
     */
    @PostMapping("/speechAssessment")
    public R speechAssessment(@RequestParam("file") MultipartFile file,@RequestParam("text") String text) throws Exception {
        return wordService.speechAssessment(file,text);
    }

    /**
     * 通过手机号发送提醒短信
     * @return 返回发送状态
     */
    @Scheduled(cron ="0 0 23 * * ?")
    public void send() {
        remindService.send();
    }

    /**
     * 插入一个典故
     * @param story
     * @return
     */
    @PostMapping("/insertStory")
    public R insertStory(StoryDTO story) throws IOException {
        return storyService.insertStory(story);
    }

    /**
     * 获取所有典故的信息
     * @param id
     * @return
     */
    @GetMapping("/getStory")
    public R getStory(@RequestParam Integer id) {
        return storyService.getStory(id);
    }

    /**
     * 插入一条问题
     * @param question
     * @return
     */
    @PostMapping("/insertQuestion")
    public R insertQuestion(@RequestBody Question question) {
        questionService.save(question);
        return R.ok();
    }

    /**
     * 获取全部问题
     * @return
     */
    @GetMapping("/getAllQuestion")
    public R getAllQuestion() {
        return R.ok(questionService.list());
    }

    /**
     * 从数据库中随机获取一个单词
     * @return
     */
    @GetMapping("/getRandomWord")
    public R getRandomWord() {
        return wordService.getRandomWord();
    }

    /**
     * 发布一条内容
     * @param communityDTO
     * @param username
     * @return
     */
    @PostMapping("/publish")
    public R publish(@RequestBody CommunityDTO communityDTO, @RequestParam String username) throws IOException {
        return communityService.publish(communityDTO,username);
    }

    /**
     * 随机获取两个指定板块的内容
     * @param type
     * @param username
     * @return
     */
    @GetMapping("/flush")
    public R flush(@RequestParam Integer type,@RequestParam String username) {
        return communityService.flush(type,username);
    }

    /**
     * 对社区内容点赞 已经点过赞就取消
     * @param id
     * @param username
     * @return
     */
    @PostMapping("/like")
    public R like(@RequestParam Integer id,@RequestParam String username) {
        return communityService.like(id,username);
    }

    /**
     * 根据id获取社区内容的一些数据
     * @param id
     * @param username
     * @return
     */
    @GetMapping("/getCommunityById")
    public R getCommunityById(@RequestParam Integer id,@RequestParam String username) {
        return communityService.getCommunityById(id,username);
    }

    /**
     * 角色模拟相关接口 玩家注册
     * @param player
     * @return 玩家注册后的id
     */
    @PostMapping("/playerRegister")
    public R playerRegister(@RequestBody Player player) throws Exception {
        return aiService.playerRegister(player);
    }

    /**
     * 角色模拟相关接口 创建人格信息
     * @param agentDTO
     * @return 新增的人格的id
     * @throws Exception
     */
    @PostMapping("/agentCreate")
    public R agentCreate(@RequestBody AgentDTO agentDTO) throws Exception {
        return aiService.agentCreate(agentDTO);
    }

    /**
     * 获取全部人格
     * @return
     */
    @GetMapping("/getAllAgent")
    public R getAllAgent() {
        return R.ok(agentService.list());
    }

    /**
     * 角色模拟相关接口 玩家与人格进行对话
     * @param question
     * @return
     */
    @GetMapping(value = "/characterSimulationChat", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    public SseEmitter characterSimulationChat(@RequestParam("question") String question, @RequestParam("agentId") String agentId,@RequestParam String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,username);
        Long userId = Long.valueOf(userService.getOne(queryWrapper).getId());
        final SseEmitter emitter = aiService.getConn(userId);
        // 使用UUID生成chatID
        String chatId = UUID.randomUUID().toString().substring(0, 10);
        if ( preChatId == null ) {
            preChatId = chatId;
        }
        CompletableFuture.runAsync(()->{
            StringBuilder answerCache = new StringBuilder();
            CharacterSimulationListener characterSimulationListener;
            try {
                characterSimulationListener = aiService.characterSimulationChat(question, answerCache,agentId,chatId,preChatId);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            int lastIdx = 0, len = 0;
            try {
                while (!characterSimulationListener.getWsCloseFlag()) {
                    if(lastIdx < (len = answerCache.length())){
                        String sendMessage = answerCache.substring(lastIdx, len);
                        // 替换所有回车换行 空格替换为占位符
                        sendMessage = sendMessage.replaceAll(" ","&#32;").replaceAll("\n", "&#92n");
                        System.out.println("发送数据=>" + sendMessage);
                        emitter.send(sendMessage);
                        lastIdx = len;
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        preChatId = chatId;
        return emitter;
    }

    /**
     * 插入一个用户
     * @param user
     * @return
     */
    @PostMapping("/insertUser")
    public R insertUser(@RequestBody User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,user.getUsername());
        if (userService.getOne(queryWrapper) == null) {
            userService.save(user);
            return R.ok();
        }
        return R.ok();
    }

    /**
     * 上传文件
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public R upload(MultipartFile file) throws IOException {
        return R.ok(ossUtil.upload(file));
    }

    /**
     * 发布评论
     * @param comment
     * @param username
     * @return
     */
    @PostMapping("/publishComment")
    public R publishComment(@RequestBody Comment comment,@RequestParam String username) {
        return commentService.publishComment(comment,username);
    }

    /**
     * 获取指定社区内容的评论
     * @param commentId
     * @return
     */
    @GetMapping("/getCommentById")
    public R getCommentById(@RequestParam Integer commentId) {
        return commentService.getCommentById(commentId);
    }

    @GetMapping("/getLearnDetail")
    public R getLearnDetail(@RequestParam String username) {
        return wordService.getLearnDetail(username);
    }


}
